var assert = require('assert');
var logger = using('easynode.framework.Logger').forFile(__filename);
var GenericObject = using('easynode.GenericObject');
var BeanFactory = using('easynode.framework.BeanFactory');
var thunkify = require('thunkify');
var fs = require('fs');
var WXPay = require('weixin-pay');
var util = require('./payMentUtil');
var request = require("co-request");
var md5 = require('MD5');
var ActionResult = using('easynode.framework.mvc.ActionResult');


(function () {
        const RETURN_CODE_SUCCESS = 'SUCCESS';
        const RETURN_CODE_FAIL = 'FAIL';

        /**
         * Class WXPayment
         *
         * @class #NAMESPACE#.WXPayment
         * @extends easynode.GenericObject
         * @since 0.1.0
         * @author zlbbq
         * */
        class WXPayment extends GenericObject {
                /**
                 * 构造函数。
                 *
                 * @method 构造函数
                 * @since 0.1.0
                 * @author zlbbq
                 * */
                constructor() {
                        super();
                        //调用super()后再定义子类成员。
                        this.cache = null;
                }

                /**
                 * 初始化连接参数。
                 *
                 * @method get
                 * @param {String} key 键
                 * @param {Object} defaultValue 默认值，默认null
                 * @return {Object} 返回缓存的值
                 * @async
                 * @since 0.1.0
                 * @author zlbbq
                 * */
                initialize(options = {}) {
                        var me = this;
                        this.options = options;
                        //for test
                        this.options.appid = 'wx95f1a889c5042df0';
                        this.options.mch_id = '1246937801';

                        this.wxpayID = {appid: this.options.appid, mch_id: this.options.mch_id};

                        EasyNode.DEBUG && logger.debug("WX PAY INITED");
                }


                sign(param) {
                        var querystring = Object.keys(param).filter(function (key) {
                                        return param[key] !== undefined && param[key] !== '' && ['pfx', 'partner_key', 'sign', 'key'].indexOf(key) < 0;
                                }).sort().map(function (key) {
                                        return key + '=' + param[key];
                                }).join("&") + "&key=" + this.options.partner_key;

                        return md5(querystring).toUpperCase();
                }


                getPaymentParams(order) {
                        var me = this;
                        order.trade_type = "JSAPI";
                        return function *() {
                                var data = yield me.createUnifiedOrder(order);

                                if (data.return_code == RETURN_CODE_SUCCESS) {
                                        if (data.result_code == RETURN_CODE_SUCCESS) {
                                                var reqparam = {
                                                        appId: me.options.appid,
                                                        timeStamp: Math.floor(Date.now() / 1000) + "",
                                                        nonceStr: data.nonce_str,
                                                        package: "prepay_id=" + data.prepay_id,
                                                        signType: "MD5"
                                                };
                                                reqparam.paySign = me.sign(reqparam);

                                                return ActionResult.createSuccessResult(reqparam);
                                        }
                                        else {
                                                return ActionResult.createErrorResult('业务受理失败,请重试!');
                                        }

                                }
                                else if (data.return_code == RETURN_CODE_FAIL) {
                                        return ActionResult.createErrorResult('下订单失败:[' + data.return_msg + ']');
                                }
                                else
                                        return ActionResult.createErrorResult('下订单发生一个位置错误!');
                        }
                }


                createUnifiedOrder(opts) {
                        var me = this;
                        opts.nonce_str = opts.nonce_str || util.generateNonceString();
                        util.mix(opts, me.wxpayID);
                        opts.sign = this.sign(opts);

                        return function *() {
                                logger.error('unifiedorder request' + util.buildXML(opts));
                                var result = yield request({
                                        uri: "https://api.mch.weixin.qq.com/pay/unifiedorder",
                                        method: "POST",
                                        body: util.buildXML(opts),
                                        agentOptions: {
                                                pfx: me.options.pfx,
                                                passphrase: me.options.mch_id
                                        }
                                });

                                return yield  util.parseXML(result.body);
                        }
                }

                useWXCallback() {
                        var me = this;
                        return function *() {
                                var data=yield me.util.pipe(this.ctx);
                                var xml = data.toString('utf8');
                               return yield  util.parseXML(xml);
                        }
                }


                getClassName() {
                        return EasyNode.namespace(__filename);
                }
        }

        module.exports = WXPayment;
})();